package com.atguigu.reflect;

import org.junit.jupiter.api.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class TestCar {

    // 1、获取Car的Class对象
    @Test
    public void test1() throws Exception {
        // 1、类名.class
        Class clazz1 = Car.class;
        // 2、对象.getClass()
//        Class<? extends Car> clazz2 = new Car().getClass();
        // 3、Class.forName("全类名")
        Class clazz3 = Class.forName("com.atguigu.reflect.Car");

        // 实例化对象
        Car car = (Car)clazz3.getDeclaredConstructor().newInstance();
        System.out.println(car);
    }
    // 2、获取构造方法
    @Test
    public void test2() throws Exception {
        Class clazz = Car.class;
//        Constructor[] constructors = clazz.getConstructors(); // 获取所有公共(public)的构造方法
        Constructor[] constructors = clazz.getDeclaredConstructors(); // 获取所有（public,private）构造方法
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName() + " " + constructor.getParameterCount());
        }

        // 1、 指定有参构造，创建对象
        Constructor constructor = clazz.getConstructor(String.class, double.class, int.class, String.class);
        Car car = (Car)constructor.newInstance("法拉利", 1000000, 2020, "红色");
        System.out.println(car);

        // 2、构造私有（private）的构造方法，创建对象
        Constructor constructor2 = clazz.getDeclaredConstructor(String.class, double.class, int.class, String.class);
        constructor2.setAccessible(true); // 修改访问权限
        Car car2 = (Car)constructor2.newInstance("保时捷", 800000, 2020, "黑色");
        System.out.println(car2);

    }
    // 3、获取成员变量
    @Test
    public void test3() throws Exception {
        Class clazz = Car.class;
        Constructor constructor = clazz.getDeclaredConstructor(); // 无参构造方法是私有
        constructor.setAccessible(true); // 修改访问权限
        Car car = (Car)constructor.newInstance();
        // 获取所有PUblic属性
//        Field[] fields = clazz.getFields();
        // 获取所有属性(public,private)
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            if (field.getName().equals("name")) {
                field.setAccessible(true);
                field.set(car, "保时捷");
            }
            System.out.println(field.getName());
            System.out.println(car);
        }
    }
    // 4、获取成员方法
    @Test
    public void test4() throws Exception {
        Car car = new Car("泵池", 1000000, 2020, "红色");
        Class clazz = car.getClass();

        // 调用共用（PUBLIC）方法
        Method[] methodsPublic = clazz.getMethods();
        for (Method method : methodsPublic) {
            System.out.println(method.getName());
            if (method.getName().equals("toString")) {
                // 调用方法
                String toString = (String)method.invoke(car);
                System.out.println(toString);
            }
        }

        Method[] methodsAll = clazz.getDeclaredMethods();
        // 调用私有（PRIVATE）方法
        for (Method method : methodsAll) {
            if (method.getName().equals("run")) {
                System.out.println("PRIVATE:" + method.getName());
                method.setAccessible(true);
                method.invoke(car);
            }
        }
    }
}
